package cn.qio.event;

import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import cn.qio.channel.ThreadSelector;
import cn.qio.channel.session.ChannelSession;

/**
 * event dispatcher 实现类
 * 
 * @author chenhua
 *
 */
public class OrderedEventDispatcher implements EventDispatcher {

	private final List<ThreadSelector> selectList;

	private boolean isStarted = false;

	public OrderedEventDispatcher(int threadPoolSize) throws IOException {
		selectList = new ArrayList<>();
		for (int i = 1; i < threadPoolSize; i++) { // 创建多个selector并启动
			selectList.add(new ThreadSelector(Selector.open()));
		}
	}

	@Override
	public void register(ChannelSession csession, int interOpts) throws ClosedChannelException {
		if (!isStarted) {
			throw new RuntimeException("event dispacher is not started.");
		}
		SocketChannel sc = csession.getSocketChannel();
		ThreadSelector threadSelector = chooseLessSessionSelector();
		sc.register(threadSelector.getSelector(), SelectionKey.OP_READ | SelectionKey.OP_WRITE, csession); // 注册读写事件
	}

	/**
	 * 返回当前关联的channelSession数目最少的一个 selector
	 * 
	 * @return
	 */
	private ThreadSelector chooseLessSessionSelector() {
		Collections.sort(selectList, (a, b) -> b.getChannelSessionSize() - a.getChannelSessionSize());
		return selectList.get(0);
	}

	@Override
	public void start() {
		for (int i = 0; i < selectList.size(); i++) { // 创建多个selector并启动
			selectList.get(i).start();
		}
		isStarted = true;
	}

	@Override
	public boolean isStarted() {
		return isStarted;
	}

	@Override
	public void stop() {
		for (int i = 0; i < selectList.size(); i++) { // 1.停止所有的selector
			selectList.get(i).setToStop(true);
		}
	}

}
